package com.jichangxiu.flow.server.core.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.jichangxiu.flow.server.core.entity.Bo.ElBo;
import com.jichangxiu.flow.server.core.entity.Bo.NodeBo;
import com.jichangxiu.flow.server.core.entity.Bo.ProcessBo;
import com.jichangxiu.flow.server.core.enums.CategoryEnums;
import com.jichangxiu.flow.server.core.enums.ComponentEnum;
import com.jichangxiu.flow.server.core.enums.MethodEnums;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ElUtils:
 *
 * @author Jcx
 * @create 2025-01-01 00:00:00
 */
public class ElUtils {

    public static Map<String, Boolean> processIdByIfStartToMap = new HashMap<>();

    public static String buildEl(ElBo elBo) {
        Map<String, String> processIdByElToMap = new HashMap<>();
        // 循环里面的子流程
        List<ProcessBo> cycleProcessBoList = elBo.getCycleProcessBoList();
        if (ObjectUtil.isNotEmpty(cycleProcessBoList)) {
            for (ProcessBo processBo : cycleProcessBoList) {
                StringBuilder stringBuilder = buildElByProcess(elBo, processBo, processIdByElToMap);
                processIdByElToMap.put(BaseUtils.getCycleReplaceKey(processBo.getBrotherId() + "_" + processBo.getId()), stringBuilder.toString());
            }
        }
        // 普通子流程
        List<ProcessBo> commonProcessBoList = elBo.getCommonProcessBoList();
        if (ObjectUtil.isNotEmpty(commonProcessBoList)) {
            for (ProcessBo processBo : commonProcessBoList) {
                StringBuilder stringBuilder = buildElByProcess(elBo, processBo, processIdByElToMap);
                processIdByElToMap.put(BaseUtils.getCommonReplaceKey(processBo.getBrotherId() + "_" + processBo.getId()), stringBuilder.toString());
            }
        }
        // 主要流程
        ProcessBo mainProcessBo = elBo.getMainProcessBo();
        StringBuilder stringBuilder = buildElByProcess(elBo, mainProcessBo, processIdByElToMap);
        String el = stringBuilder.toString();
        for (NodeBo nodeBo : elBo.getLiteFlowContext().getNodeBoList()) {
            el = el.replace(nodeBo.getId(), nodeBo.getCode());
        }
        return el;
    }

    private static StringBuilder buildElByProcess(ElBo elBo, ProcessBo processBo, Map<String, String> processIdByElToMap) {
        processIdByIfStartToMap = new HashMap<>();
        processIdByIfStartToMap.put(processBo.getId(), false);
        NodeBo nodeBo = processBo.getNodeBo();
        StringBuilder el = new StringBuilder();
        String rootMethod = getProcessStartMethod(nodeBo);
        StringBuilder elStringBuilder = recursionBuildEl(elBo, processBo, nodeBo, processIdByElToMap);
        if (StrUtil.isNotEmpty(rootMethod) && elStringBuilder.toString().contains(",")) {
            el.append(rootMethod).append("(").append(elStringBuilder).append(")");
        } else {
            el = elStringBuilder;
        }
        return el;
    }

    private static StringBuilder recursionBuildEl(ElBo elBo, ProcessBo processBo, NodeBo nodeBo, Map<String, String> processIdByElToMap) {
        List<NodeBo> childNodeBoList = nodeBo.getChildNodeBoList();
        boolean exitsCommonProcess = elBo.getCommonProcessBrotherIdList().contains(nodeBo.getId());
        boolean exitsCycleProcess = elBo.getCycleProcessBrotherIdList().contains(nodeBo.getId());
        String currentComponent = getComponent(processBo, nodeBo);
        NodeBo parentNodeBo = TreeUtils.findNodeBoById(elBo.getLiteFlowContext().getRootNodeBo(), nodeBo.getParentId());
        NodeBo grantFatherNodeBo = ObjectUtil.isNotEmpty(parentNodeBo)
                ? TreeUtils.findNodeBoById(elBo.getLiteFlowContext().getRootNodeBo(), parentNodeBo.getParentId())
                : null;
        String currentMethod = ObjectUtil.isEmpty(grantFatherNodeBo) && ObjectUtil.isEmpty(parentNodeBo)
                ? getProcessStartMethod(nodeBo)
                : ObjectUtil.isNotEmpty(parentNodeBo)
                ? getMethodByNodeBo(parentNodeBo)
                : "";
        String nextMethod = getNextMethod(grantFatherNodeBo, parentNodeBo, nodeBo);
        String nodeBoCategory = nodeBo.getCategory();
        boolean isNextBuild = isNextBuild(childNodeBoList);
        StringBuilder el = new StringBuilder();
        // COMMON
        if (CategoryEnums.COMMON.name().equals(nodeBoCategory)) {
            boolean opened = false;
            // 渲染当前节点（带id才渲染）
            if (StrUtil.isNotEmpty(nodeBo.getId())) {
                if (isNextBuild) {
                    if (MethodEnums.THEN.name().equals(currentMethod)) {
                        el.append(currentComponent).append(nodeBo.getId()).append(",");
                    } else {
                        el.append(MethodEnums.THEN.name()).append("(").append(currentComponent).append(nodeBo.getId()).append(",");
                        opened = true;
                    }
                } else {
                    el.append(currentComponent).append(nodeBo.getId());
                }
            }
            // 渲染子节点
            if (isNextBuild) {
                boolean childMethodOpened = false;
                // 如果需要切换到下一个运行方式
                if (StrUtil.isNotEmpty(nextMethod) && !MethodEnums.THEN.name().equals(nextMethod)) {
                    el.append(nextMethod).append("(");
                    childMethodOpened = true;
                }
                for (int i = 0; i < childNodeBoList.size(); i++) {
                    StringBuilder childEl = recursionBuildEl(elBo, processBo, childNodeBoList.get(i), processIdByElToMap);
                    if (i > 0 && StrUtil.isNotEmpty(childEl)) {
                        el.append(",");
                    }
                    el.append(childEl);
                }
                if (childMethodOpened) {
                    el.append(")");
                }
            }
            // 关闭之前打开的
            if (opened) {
                el.append(")");
            }
            // 如果有兄弟流程（子流程），加上替换占位符
            if (exitsCommonProcess) {
                List<String> processList = getCommonProcessByMap(processIdByElToMap, nodeBo.getId());
                if (ObjectUtil.isNotEmpty(processList)) {
                    for (String commonProcess : processList) {
                        el.append(",").append(commonProcess);
                    }
                }
            }
        }
        // SWITCH
        else if (CategoryEnums.SWITCH.name().equals(nodeBoCategory)) {
            boolean opened = false;
            if (exitsCommonProcess) {
                List<String> processList = getCommonProcessByMap(processIdByElToMap, nodeBo.getId());
                if (processList.size() > 1) {
                    el.append(MethodEnums.THEN.name()).append("(");
                } else if (!currentMethod.equals(MethodEnums.THEN.name())) {
                    el.append(MethodEnums.THEN.name()).append("(");
                } else {
                    String commonProcess = processList.get(0);
                    if (!(commonProcess.startsWith(ComponentEnum.SWITCH.name())
                            || commonProcess.startsWith(ComponentEnum.IF.name())
                            || commonProcess.startsWith(ComponentEnum.FOR.name())
                            || commonProcess.startsWith(ComponentEnum.WHILE.name())
                            || commonProcess.startsWith(ComponentEnum.ITERATOR.name()))
                            && commonProcess.contains(",")) {
                        el.append(MethodEnums.THEN.name()).append("(");
                    }
                }
            }
            // 渲染当前节点（带id才渲染）
            if (StrUtil.isNotEmpty(nodeBo.getId())) {
                el.append(currentComponent).append("(").append(nodeBo.getId()).append(")").append(".TO").append("(");
                opened = true;
            }
            // 渲染子节点
            if (isNextBuild) {
                for (int i = 0; i < childNodeBoList.size(); i++) {
                    NodeBo childNodeBo = childNodeBoList.get(i);
                    String childNodeBoTag = BaseUtils.getTagByNodeBo(childNodeBo);
                    BigDecimal count = TreeUtils.getAllChildNodeBoCount(childNodeBo, false);
                    StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, childNodeBo, processIdByElToMap);
                    if (i > 0 && ObjectUtil.isNotEmpty(stringBuilder) && StrUtil.isNotEmpty(stringBuilder))
                        el.append(",");
                    if (count.compareTo(BigDecimal.ONE) == 0) {
                        // 如果子项是一个组件，直接添加
                        el.append(stringBuilder);
                    } else if (stringBuilder.toString().startsWith(MethodEnums.THEN.name()) || stringBuilder.toString().startsWith(MethodEnums.WHEN.name())) {
                        // 如果子组件已经被包裹，则直接添加
                        el.append(stringBuilder);
                    } else if (!stringBuilder.toString().contains(",")) {
                        // 如果子项只是一个节点，则直接添加
                        el.append(stringBuilder);
                    } else {
                        // 如果子项不是一个组件，而是一个组件树 则需要被 THEN 包起来
                        el.append(MethodEnums.THEN.name()).append("(").append(stringBuilder).append(")");
                    }
                    if (ObjectUtil.isNotEmpty(childNodeBoTag)) {
                        el.append(".tag('").append(childNodeBoTag).append("')");
                    }
                }
            }
            // 当前节点结束标记
            if (opened) {
                el.append(")");
            }
            if (exitsCommonProcess) {
                // 存在兄弟流程
                List<String> processList = getCommonProcessByMap(processIdByElToMap, nodeBo.getId());
                if (ObjectUtil.isNotEmpty(processList)) {
                    for (String commonProcess : processList) {
                        if (StrUtil.isNotEmpty(commonProcess)) {
                            el.append(",").append(commonProcess);
                        }
                    }
                    if (processList.size() > 1) {
                        el.append(")");
                    } else if (!currentMethod.equals(MethodEnums.THEN.name())) {
                        el.append(")");
                    } else {
                        String commonProcess = processList.get(0);
                        if (!(commonProcess.startsWith(ComponentEnum.SWITCH.name())
                                || commonProcess.startsWith(ComponentEnum.IF.name())
                                || commonProcess.startsWith(ComponentEnum.FOR.name())
                                || commonProcess.startsWith(ComponentEnum.WHILE.name())
                                || commonProcess.startsWith(ComponentEnum.ITERATOR.name()))
                                && commonProcess.contains(",")) {
                            el.append(")");
                        }
                    }
                }
            }
        }
        // BOOLEAN
        else if (CategoryEnums.BOOLEAN.name().equals(nodeBoCategory)) {
            processIdByIfStartToMap.put(nodeBo.getId(), true);
            if (exitsCommonProcess) {
                List<String> processList = getCommonProcessByMap(processIdByElToMap, nodeBo.getId());
                if (processList.size() > 1) {
                    el.append(MethodEnums.THEN.name()).append("(");
                } else if (!currentMethod.equals(MethodEnums.THEN.name())) {
                    el.append(MethodEnums.THEN.name()).append("(");
                } else {
                    String commonProcess = processList.get(0);
                    if (!(commonProcess.startsWith(ComponentEnum.SWITCH.name())
                            || commonProcess.startsWith(ComponentEnum.IF.name())
                            || commonProcess.startsWith(ComponentEnum.FOR.name())
                            || commonProcess.startsWith(ComponentEnum.WHILE.name())
                            || commonProcess.startsWith(ComponentEnum.ITERATOR.name()))
                            && commonProcess.contains(",")) {
                        el.append(MethodEnums.THEN.name()).append("(");
                    }
                }
            }
            if (childNodeBoList.size() != 2) {
                throw new RuntimeException("判断组件下必须且只能存在两个子节点");
            }
            List<String> categoryList = childNodeBoList.stream().map(NodeBo::getCategory).collect(Collectors.toList());
            if (ObjectUtil.isEmpty(categoryList) || categoryList.size() != 2) {
                throw new RuntimeException("判断组件下必须且只能存在两个子节点");
            }
            NodeBo trueNodeBo = BaseUtils.getBooleanTrueNodeBo(childNodeBoList);
            if (ObjectUtil.isNull(trueNodeBo)) {
                throw new RuntimeException("判断组件下必须存在一条结果为真的路线");
            }
            NodeBo falseNodeBo = BaseUtils.getBooleanFalseNodeBo(childNodeBoList);
            if (ObjectUtil.isNull(falseNodeBo)) {
                throw new RuntimeException("判断组件下必须存在一条结果为假的路线");
            }
            String trueNodeBoCategory = trueNodeBo.getCategory();
            BigDecimal trueCount = TreeUtils.getAllChildNodeBoCount(trueNodeBo, false);
            if (trueNodeBoCategory.equals(CategoryEnums.BOOLEAN.name())) {
                throw new RuntimeException("多个布尔组件情况下不能让子布尔组件放在false路线上");
            }
            String falseNodeBoCategory = falseNodeBo.getCategory();
            BigDecimal falseCount = TreeUtils.getAllChildNodeBoCount(falseNodeBo, false);
            // 渲染当前节点（带id才渲染）
            if (StrUtil.isNotEmpty(nodeBo.getId())) {
                el.append(currentComponent).append("(").append(nodeBo.getId()).append(",");
            }
            // 渲染子节点
            if (isNextBuild) {
                // 处理 true 节点
                if (trueCount.compareTo(BigDecimal.ONE) == 0) {
                    el.append(recursionBuildEl(elBo, processBo, trueNodeBo, processIdByElToMap));
                } else {
                    StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, trueNodeBo, processIdByElToMap);
                    el.append(MethodEnums.THEN.name()).append("(").append(stringBuilder).append(")");
                }
                // 不是三元表达式，当前 true 直接闭合
                if (falseCount.compareTo(BigDecimal.ONE) != 0) {
                    el.append(")");
                }
                // 处理 false 节点
                if (falseNodeBoCategory.equals(CategoryEnums.BOOLEAN.name())) {
                    // 是 boolean 类型
                    StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, falseNodeBo, processIdByElToMap);
                    if (ObjectUtil.isNotEmpty(stringBuilder) && StrUtil.isNotEmpty(stringBuilder)) {
                        el.append(".").append(stringBuilder);
                    }
                }
                // 不是 boolean 类型
                else {
                    if (falseCount.compareTo(BigDecimal.ONE) == 0) {
                        // 三元表达式，最后闭合三元表达式
                        StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, falseNodeBo, processIdByElToMap);
                        if (ObjectUtil.isNotEmpty(stringBuilder) && StrUtil.isNotEmpty(stringBuilder)) {
                            el.append(",").append(stringBuilder).append(")");
                        } else {
                            // 如果是空的，也要闭合三元
                            el.append(")");
                        }
                    } else {
                        StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, falseNodeBo, processIdByElToMap);
                        if (ObjectUtil.isNotEmpty(stringBuilder) && StrUtil.isNotEmpty(stringBuilder)) {
                            el.append(".ELSE").append("(");
                            if (stringBuilder.toString().contains(",")) {
                                el.append("THEN(").append(stringBuilder).append(")");
                            } else {
                                el.append(stringBuilder);
                            }
                            el.append(")");
                        }
                    }
                }
            }
            // 处理子流程
            if (exitsCommonProcess) {
                // 存在兄弟流程
                List<String> processList = getCommonProcessByMap(processIdByElToMap, nodeBo.getId());
                if (ObjectUtil.isNotEmpty(processList)) {
                    for (String commonProcess : processList) {
                        if (StrUtil.isNotEmpty(commonProcess)) {
                            el.append(",").append(commonProcess);
                        }
                    }
                    if (processList.size() > 1) {
                        el.append(")");
                    } else if (!currentMethod.equals(MethodEnums.THEN.name())) {
                        el.append(")");
                    } else {
                        String commonProcess = processList.get(0);
                        if (!(commonProcess.startsWith(ComponentEnum.SWITCH.name())
                                || commonProcess.startsWith(ComponentEnum.IF.name())
                                || commonProcess.startsWith(ComponentEnum.FOR.name())
                                || commonProcess.startsWith(ComponentEnum.WHILE.name())
                                || commonProcess.startsWith(ComponentEnum.ITERATOR.name()))
                                && commonProcess.contains(",")) {
                            el.append(")");
                        }
                    }
                }
            }
            return el;
        }
        // MARK
        else if (CategoryEnums.MARK.name().equals(nodeBoCategory)) {
            if (isNextBuild) {
                if (!currentMethod.equals(nextMethod)) {
                    el.append(nextMethod).append("(");
                }
                for (int i = 0; i < childNodeBoList.size(); i++) {
                    StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, childNodeBoList.get(i), processIdByElToMap);
                    if (i > 0 && ObjectUtil.isNotEmpty(stringBuilder) && StrUtil.isNotEmpty(stringBuilder)) {
                        el.append(",");
                    }
                    el.append(stringBuilder);
                }
                if (!currentMethod.equals(nextMethod)) {
                    el.append(")");
                }
            }
        }
        // FOR || WHILE || ITERATOR
        else if (CategoryEnums.FOR.name().equals(nodeBoCategory)
                || CategoryEnums.WHILE.name().equals(nodeBoCategory)
                || CategoryEnums.ITERATOR.name().equals(nodeBoCategory)) {
            boolean opened = false;
            // 处理本节点：本节点Code不能为空，否则不处理
            if (StrUtil.isNotEmpty(nodeBo.getId())) {
                el.append(currentComponent).append("(").append(nodeBo.getId()).append(")").append(".DO").append("(");
                opened = true;
            }
            // 处理子节点
            if (isNextBuild) {
                for (int i = 0; i < childNodeBoList.size(); i++) {
                    NodeBo childNodeBo = childNodeBoList.get(i);
                    BigDecimal count = TreeUtils.getAllChildNodeBoCount(childNodeBo, false);
                    StringBuilder stringBuilder = recursionBuildEl(elBo, processBo, childNodeBo, processIdByElToMap);
                    if (i > 0 && ObjectUtil.isNotEmpty(stringBuilder) && StrUtil.isNotEmpty(stringBuilder))
                        el.append(",");
                    if (count.compareTo(BigDecimal.ONE) == 0) {
                        // 如果只有一个组件直接添加
                        el.append(stringBuilder);
                    } else if (stringBuilder.toString().startsWith(MethodEnums.THEN.name()) || stringBuilder.toString().startsWith(MethodEnums.WHEN.name())) {
                        // 如果组件已经被包裹，则不需要再次包裹
                        el.append(stringBuilder);
                    } else {
                        // 如果子项不是一个组件，而是一个组件树 则需要被 THEN 包起来
                        el.append(MethodEnums.THEN.name()).append("(").append(stringBuilder).append(")");
                        if (i != childNodeBoList.size() - 1) el.append(",");
                    }
                }
            }
            if (exitsCycleProcess) {
                // 存在兄弟流程
                List<String> processList = getCycleProcessByMap(processIdByElToMap, nodeBo.getId());
                if (ObjectUtil.isNotEmpty(processList)) {
                    if (processList.size() > 1) {
                        el.append(MethodEnums.THEN.name()).append("(");
                    }
                    for (int i = 0; i < processList.size(); i++) {
                        String cycleProcess = processList.get(i);
                        el.append(cycleProcess);
                        if (i != processList.size() - 1) {
                            el.append(",");
                        }
                    }
                    if (processList.size() > 1) {
                        el.append(")");
                    }
                }
            }
            // 本节点结束标记
            if (opened) {
                el.append(")");
            }
        }
        return el;
    }

    private static List<String> getCommonProcessByMap(Map<String, String> processIdByElToMap, String nodeId) {
        List<String> processList = new ArrayList<>();
        for (String key : processIdByElToMap.keySet()) {
            String s = BaseUtils.getCommonReplaceKey(nodeId).replace("</RP_COMMON>", "") + "_";
            if (key.startsWith(s)) {
                processList.add(processIdByElToMap.get(key));
            }
        }
        return processList;
    }

    private static List<String> getCycleProcessByMap(Map<String, String> processIdByElToMap, String nodeId) {
        List<String> processList = new ArrayList<>();
        for (String key : processIdByElToMap.keySet()) {
            String s = BaseUtils.getCycleReplaceKey(nodeId).replace("</RP_CYCLE>", "") + "_";
            if (key.startsWith(s)) {
                processList.add(processIdByElToMap.get(key));
            }
        }
        return processList;
    }

    /**
     * 获取组件字符串
     *
     * @param processBo 当前流程
     * @param nodeBo    当前节点
     * @return 组件字符串
     */
    private static String getComponent(ProcessBo processBo, NodeBo nodeBo) {
        if (CategoryEnums.COMMON.name().equals(nodeBo.getCategory())) {
            return "";
        } else if (CategoryEnums.SWITCH.name().equals(nodeBo.getCategory())) {
            return ComponentEnum.SWITCH.name();
        } else if (CategoryEnums.BOOLEAN.name().equals(nodeBo.getCategory())) {
            if (!processIdByIfStartToMap.get(processBo.getId())) return ComponentEnum.IF.name();
            else return ComponentEnum.ELIF.name();
        } else if (CategoryEnums.FOR.name().equals(nodeBo.getCategory())) {
            return ComponentEnum.FOR.name();
        } else if (CategoryEnums.WHILE.name().equals(nodeBo.getCategory())) {
            return ComponentEnum.WHILE.name();
        } else if (CategoryEnums.ITERATOR.name().equals(nodeBo.getCategory())) {
            return ComponentEnum.ITERATOR.name();
        } else {
            return "";
        }
    }

    /**
     * 是否有子节点需要构建
     *
     * @param nodeBoList 节点集合
     * @return 是否需要继续构建
     */
    private static boolean isNextBuild(List<NodeBo> nodeBoList) {
        if (ObjectUtil.isEmpty(nodeBoList)) return false;
        List<String> categoryList = nodeBoList.stream().map(NodeBo::getCategory).distinct().collect(Collectors.toList());
        return !ObjectUtil.isNotEmpty(categoryList) || categoryList.size() != 1 || !categoryList.contains(CategoryEnums.MARK.name());
    }

    /**
     * 根据传入的根节点获取处理方式
     *
     * @param rootNodeBo 根节点
     * @return 根节点的处理方式
     */
    private static String getProcessStartMethod(NodeBo rootNodeBo) {
        String rootCategory = rootNodeBo.getCategory();
        if (ObjectUtil.isNotEmpty(rootNodeBo.getChildNodeBoList()) && rootNodeBo.getChildNodeBoList().size() == 1) {
            String subCategory = rootNodeBo.getChildNodeBoList().get(0).getCategory();
            if (CategoryEnums.SWITCH.name().equals(subCategory)
                    || CategoryEnums.FOR.name().equals(subCategory)
                    || CategoryEnums.WHILE.name().equals(subCategory)
                    || CategoryEnums.ITERATOR.name().equals(subCategory)) {
                return "";
            }
        } else if (CategoryEnums.SWITCH.name().equals(rootCategory)
                || CategoryEnums.FOR.name().equals(rootCategory)
                || CategoryEnums.WHILE.name().equals(rootCategory)
                || CategoryEnums.ITERATOR.name().equals(rootCategory)) {
            return "";
        }
        return MethodEnums.THEN.name();
    }

    /**
     * 根据传入的节点获取处理方式
     *
     * @param nodeBo 节点
     * @return 节点的处理方式
     */
    private static String getMethodByNodeBo(NodeBo nodeBo) {
        String nodeBoCategory = nodeBo.getCategory();
        int childCount = ObjectUtil.isEmpty(nodeBo.getChildNodeBoList()) ? 0 : nodeBo.getChildNodeBoList().size();
        if (CategoryEnums.COMMON.name().equals(nodeBoCategory)
                || CategoryEnums.MARK.name().equals(nodeBoCategory)) {
            if (childCount > 1) {
                return MethodEnums.WHEN.name();
            } else {
                return MethodEnums.THEN.name();
            }
        } else {
            return MethodEnums.THEN.name();
        }
    }

    private static String getNextMethod(NodeBo grantFatherNodeBo, NodeBo parentNodeBo, NodeBo nodeBo) {
        // 本节点的运行方式
        String currentMethod =
                ObjectUtil.isEmpty(grantFatherNodeBo) && ObjectUtil.isEmpty(parentNodeBo) ? getProcessStartMethod(nodeBo) :
                        ObjectUtil.isNotEmpty(parentNodeBo) ? getMethodByNodeBo(parentNodeBo) : "";
        // 父节点的运行方式
        String parentMethod = ObjectUtil.isNotEmpty(grantFatherNodeBo) ? getMethodByNodeBo(grantFatherNodeBo) : "";
        // 子节点的运行方式
        String childMethod = getMethodByNodeBo(nodeBo);
        // 是否有子节点继续构建
        boolean isNextBuild = isNextBuild(nodeBo.getChildNodeBoList());
        // 子节点的运行方式与当前节点运行方式一致，可以省略
        if (childMethod.equals(currentMethod) && !isNextBuild) {
            return "";
        }
        return childMethod;
    }

}
